package com.lyeducation.services.course;

import com.lyeducation.controllers.dto.CartDTO;
import com.lyeducation.controllers.dto.CourseDTO;
import com.lyeducation.core.base.TokenConstants;
import com.lyeducation.core.course.CourseService;
import com.lyeducation.entities.course.ChapterEntity;
import com.lyeducation.entities.course.CourseEntity;
import com.lyeducation.entities.course.middle.CategoryCourseEntity;
import com.lyeducation.entities.course.middle.CourseChapterEntity;
import com.lyeducation.entities.course.middle.CourseImageEntity;
import com.lyeducation.entities.system.SysImageEntity;
import com.lyeducation.enums.CourseCarouselEnum;
import com.lyeducation.enums.ResultEnum;
import com.lyeducation.exception.LeadingEagleException;
import com.lyeducation.repository.CourseRepository;
import com.lyeducation.security.config.SecurityPrincipalContext;
import com.lyeducation.services.base.BaseServiceImpl;
import com.lyeducation.util.HttpUtils;
import com.lyeducation.util.KeyUtil;
import com.lyeducation.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.transform.Transformers;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CourseServiceImpl extends BaseServiceImpl<CourseEntity> implements CourseService {
    @Autowired
    private CourseRepository courseRepository;

    @Override
    public CourseEntity findOne(String courseId) {
        return courseRepository.findById(courseId);
    }

    @Override
    public CourseEntity updateCourse(CourseDTO courseDTO) {
        if (StringUtils.isNotBlank(courseDTO.getId()) && StringUtils.isNotBlank(courseDTO.getCategoryId())) {
            CourseEntity course = courseRepository.findById(courseDTO.getId());
            BeanUtils.copyProperties(courseDTO, course);
            if (course != null) {
                if (StringUtils.isNotBlank(courseDTO.getImgBase64())) {
                    // 获取课程封面地址
                    SysImageEntity imageEntity = new SysImageEntity();
                    imageEntity.setId(TokenConstants.generateUserId());
                    File file =
                            HttpUtils.setBase64Data(
                                    "courseImage/" + courseDTO.getId(), imageEntity.getId(), courseDTO.getImgBase64());
                    String imgUrl = "/" + file.toURI().getPath().split("classes/")[1];
                    course.setCoursePic(imgUrl);

                    imageEntity.setUrl(file.getPath());
                    imageEntity.setImgUrl(imgUrl);
                    imageEntity.setSize(file.length());
                    imageEntity.setName(file.getName());
                    Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                    imageEntity.setCreateTime(timestamp);
                    imageEntity.setCreateId(SecurityPrincipalContext.getUserDetailsImpl().getId());
                    imageEntity.setUpdateId(SecurityPrincipalContext.getUserDetailsImpl().getId());
                    imageEntity.setUpdateTime(timestamp);
                    String imageMimeType = courseDTO.getImgBase64().split(",")[0].split(";")[0].split(":")[1];
                    imageEntity.setMimeType(imageMimeType);
                    // 保存到sys_image表
                    courseRepository.update(imageEntity);

                    //保存到course_image表
                    CourseImageEntity courseImageEntity = new CourseImageEntity();
                    courseImageEntity.setImageId(imageEntity.getId());
                    courseImageEntity.setCourseId(course.getId());
                    courseRepository.update(courseImageEntity);
                }
                //更新到course表
                course = courseRepository.update(course);

                /** 保存到category_course表 */
                Map paramMap = new HashMap();
                paramMap.put("categoryId", courseDTO.getCategoryId());
                paramMap.put("courseId", course.getId());
                String hql = "as v set v.categoryId=:categoryId where v.courseId=:courseId";
                courseRepository.updateFileds(CategoryCourseEntity.class, hql, paramMap, null);

                return course;
            }
        }
        return null;
    }

    @Override
    public boolean deleteCourse(String courseId) {
        if (StringUtils.isNotBlank(courseId)) {
            //从course表中删除
            boolean course = courseRepository.deleteById(courseId);
            if (course) {
                //从course_image中间表中删除
                courseRepository.delMiddleTable(CourseImageEntity.class, "courseId", courseId, null, null);
                //从course_chapter中间表中删除
                return courseRepository.delMiddleTable(CourseChapterEntity.class, "courseId", courseId, null, null);
            }
        }
        return false;
    }

    @Override
    public Map<String, Object> courseInfo(String courseId) {
        if (StringUtils.isNotBlank(courseId)) {
            Map<String, Object> map = new HashMap<>();
            map.put("courseId", courseId);
            Map<String, Object> courseMap = courseRepository.findPageByNativeQueryFileds("select lmkc.categoryId, lm.categoryName, kc.* from category lm left join category_course lmkc on lm.id = lmkc.categoryId left join course kc on kc.id = lmkc.courseId WHERE kc.id=:courseId",
                    map, Transformers.aliasToBean(HashMap.class), null, null);
            return courseMap;
        }
        return null;
    }

    @Override
    public CourseEntity addUpdCourse(CourseDTO courseDTO) {

        if (StringUtils.isNotBlank(courseDTO.getName())) {
            if (StringUtils.trimToNull(courseDTO.getId()) != null) {
                throw new LeadingEagleException(ResultEnum.PARAM_ERROR);
            } else {
                //生成课程id
                String courseId = KeyUtil.genUniqueKey();

                // 获取课程封面地址
                SysImageEntity imageEntity = new SysImageEntity();
                imageEntity.setId(TokenConstants.generateUserId());
                File file =
                        HttpUtils.setBase64Data(
                                "courseImage/" + courseId, imageEntity.getId(), courseDTO.getImgBase64());
                String imgUrl = "/" + file.toURI().getPath().split("classes/")[1];
                imageEntity.setUrl(file.getPath());
                imageEntity.setImgUrl(imgUrl);
                imageEntity.setSize(file.length());
                imageEntity.setName(file.getName());
                Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                imageEntity.setCreateTime(timestamp);
                imageEntity.setCreateId(SecurityPrincipalContext.getUserDetailsImpl().getId());
                imageEntity.setUpdateId(SecurityPrincipalContext.getUserDetailsImpl().getId());
                imageEntity.setUpdateTime(timestamp);
                String imageMimeType = courseDTO.getImgBase64().split(",")[0].split(";")[0].split(":")[1];
                imageEntity.setMimeType(imageMimeType);
                // 保存到sys_image表
                courseRepository.save(imageEntity);

                courseDTO.setId(courseId);
                if (StringUtils.isNotBlank(imgUrl)) {
                    courseDTO.setCoursePic(imgUrl);
                }
                CourseEntity courseEntity = new CourseEntity();
                BeanUtils.copyProperties(courseDTO, courseEntity);
                /** 保存到course表 */
                courseEntity = courseRepository.saveOrUpdate(courseEntity);

                /** 保存到category_course表 */
                CategoryCourseEntity categoryCourseEntity = new CategoryCourseEntity();
                categoryCourseEntity.setCategoryId(courseDTO.getCategoryId());
                categoryCourseEntity.setCourseId(courseEntity.getId());
                courseRepository.save(categoryCourseEntity);

                //保存到course_image表
                CourseImageEntity courseImageEntity = new CourseImageEntity();
                courseImageEntity.setImageId(imageEntity.getId());
                courseImageEntity.setCourseId(courseEntity.getId());
                courseRepository.save(courseImageEntity);

                return courseEntity;
            }
        }
        return null;
    }

    @Override
    public Map<String, Object> selCourseByPage(int pageNo, int pageSize) {
        return courseRepository.findPageByNativeQueryFileds("select * from course", null, pageNo, pageSize);
    }

    @Override
    public Map<String, Object> courseEntityList(String categoryId, int pageNo, int pageSize) {
        if (StringUtils.isNotBlank(categoryId)) {
            Map<String, Object> map = new HashMap<>();
            map.put("categoryId", categoryId);
            return courseRepository.findPageByNativeQueryFileds("select lmkc.categoryId, lm.categoryName, kc.* from category lm left join category_course lmkc on lm.id = lmkc.categoryId left join course kc on kc.id = lmkc.courseId WHERE lm.id=:categoryId",
                    map, Transformers.aliasToBean(HashMap.class), pageNo, pageSize);
        } else {
            return courseRepository.findPageByNativeQueryFileds("select lmkc.categoryId, lm.categoryName, kc.* from course kc left join category_course lmkc on kc.id = lmkc.courseId left join category lm on lm.id = lmkc.categoryId",
                    null, Transformers.aliasToBean(HashMap.class), pageNo, pageSize);
        }
    }

    @Override
    @Transactional
    public void decreaseStock(List<CartDTO> cartDTOList) {
        for (CartDTO cartDTO : cartDTOList) {
            CourseEntity courseEntity = courseRepository.findById(cartDTO.getCourseId());
            if (courseEntity == null) {
                throw new LeadingEagleException(ResultEnum.PRODUCT_NOT_EXIST);
            }

            Integer result = courseEntity.getCourseStock() - cartDTO.getCourseQuantity().intValue();
            if (result < 0) {
                throw new LeadingEagleException(ResultEnum.PRODUCT_STOCK_ERROR);
            }

            courseEntity.setCourseStock(result);

            courseRepository.save(courseEntity);
        }
    }

    @Override
    public Map<String, Object> searchCourse(CourseDTO courseDTO) {
        if (!StringUtils.isNotBlank(courseDTO.getName())) {
            log.info("课程名称不能为空，课程名称：{}", courseDTO.getName());
            throw new LeadingEagleException(ResultEnum.COURSE_NAME_IS_NOT_BLANK);
        }
        String sqlCourseName = "%" + courseDTO.getName() + "%";
        Map<String, Object> map = new HashMap();
        map.put("name", sqlCourseName);
        Map<String, Object> courseEntityList = courseRepository.findPageByNativeQueryFileds("SELECT * FROM course WHERE name LIKE:name", map, courseDTO.getPageNo(), courseDTO.getPageSize());

        return courseEntityList;
    }

    @Override
    @Transactional
    public void increaseStock(List<CartDTO> cartDTOList) {
        for (CartDTO cartDTO : cartDTOList) {
            CourseEntity courseEntity = courseRepository.findById(cartDTO.getCourseId());
            if (courseEntity == null) {
                throw new LeadingEagleException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            Integer result = courseEntity.getCourseStock() + cartDTO.getCourseQuantity().intValue();
            courseEntity.setCourseStock(result);

            courseRepository.save(courseEntity);
        }
    }

    @Override
    public Map<String, Object> popularCourse(int pageNo, int pageSize) {
        Map<String, Object> map = new HashMap<>();
        map.put("isPopular", 0);
        return courseRepository.findPageByNativeQueryFileds("SELECT * FROM course c WHERE c.isPopular=:isPopular",
                map, Transformers.aliasToBean(HashMap.class), pageNo, pageSize);
    }

    @Override
    public CourseEntity courseInfoIndex(String courseId) {
        if (StringUtils.isNotBlank(courseId)) {
            CourseEntity courseEntity = courseRepository.findById(courseId);
            List<CourseChapterEntity> courseChapterEntityList = courseRepository.findByFiled(CourseChapterEntity.class, "courseId", courseId);
            List list = new ArrayList();
            for (int i = 0; i < courseChapterEntityList.size(); i++) {
                ChapterEntity chapterEntity = courseRepository.findById(ChapterEntity.class, courseChapterEntityList.get(i).getChapterId());
                list.add(chapterEntity);
            }
            courseEntity.setChapterEntityList(list);
            return courseEntity;
        }
        return null;
    }

    @Override
    public boolean isPopularCourse(String courseId, int popularCode) {
        if (StringUtils.isNotBlank(courseId) || StringUtils.isNotBlank(String.valueOf(popularCode))) {
            CourseEntity courseEntity = courseRepository.findById(courseId);
            if (courseEntity != null) {
                courseEntity.setIsPopular(popularCode);
                courseRepository.update(courseEntity);
                return true;
            }
        }
        return false;
    }

    @Override
    public List carousel() {
        int carousel = CourseCarouselEnum.YES.getCode();
        List<CourseEntity> list = courseRepository.findByFiled(CourseEntity.class, "isCarousel", carousel);
        List carouselList = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            carouselList.add(list.get(i).getCoursePic());
        }
        return carouselList;
    }

    @Override
    public boolean isCarousel(String courseId, int carousel) {
        if (StringUtils.isNotBlank(courseId) || StringUtils.isNotBlank(String.valueOf(carousel))) {
            CourseEntity courseEntity = courseRepository.findById(courseId);
            if (courseEntity != null) {
                courseEntity.setIsCarousel(carousel);
                courseRepository.update(courseEntity);
                return true;
            }
        }
        return false;
    }

    @Override
    public List<CourseEntity> videoAccessRole(int videoAccessRole) {
        List<CourseEntity> courseEntityList = courseRepository.findByFiled(CourseEntity.class, "videoAccessRoleEnum", videoAccessRole);
        return courseEntityList;
    }
}
